home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / tcp_ip / os2 / pmnos11s / ppppap.c < prev    next >
C/C++ Source or Header  |  1993-07-30  |  16KB  |  726 lines

  1. /*
  2.  *  PPPPAP.C    -- Password Authentication Protocol for PPP
  3.  *
  4.  *    This implementation of PPP is declared to be in the public domain.
  5.  *
  6.  *    Jan 91    Bill_Simpson@um.cc.umich.edu
  7.  *        Computer Systems Consulting Services
  8.  *
  9.  *    Acknowledgements and correction history may be found in PPP.C
  10.  *
  11.  * Mods by PA0GRI
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include "global.h"
  16. #include "mbuf.h"
  17. #include "proc.h"
  18. #include "iface.h"
  19. #include "session.h"
  20. #include "socket.h"
  21. #include "ppp.h"
  22. #include "pppfsm.h"
  23. #include "ppplcp.h"
  24. #include "ppppap.h"
  25. #include "cmdparse.h"
  26. #include "files.h"
  27. #include "trace.h"
  28. #include "main.h"
  29.  
  30. static int dopap_user        __ARGS((int argc, char *argv[], void *p));
  31.  
  32. static void pap_monitor __ARGS((int mustask, void *v1, void *v2));
  33. static void pap_pwdlookup __ARGS((struct pap_s *pap_p));
  34.  
  35. static struct mbuf *pap_makereq __ARGS((struct fsm_s *fsm_p));
  36.  
  37. static int pap_verify __ARGS((char *username, char *password));
  38. static void pap_shutdown __ARGS((struct fsm_s *fsm_p));
  39. static void pap_opening __ARGS((struct fsm_s *fsm_p, int flag));
  40.  
  41. static int pap_request    __ARGS((struct fsm_s *fsm_p,
  42.             struct config_hdr *hdr,
  43.             struct mbuf *data));
  44. static int pap_check    __ARGS((struct fsm_s *fsm_p,
  45.             struct config_hdr *hdr,
  46.             struct mbuf *data));
  47. static void pap_timeout    __ARGS((void *vp));
  48.  
  49. static void pap_free    __ARGS((struct fsm_s *fsm_p));
  50.  
  51.  
  52. static struct fsm_constant_s pap_constants = {
  53.     "Pap",
  54.     PPP_PAP_PROTOCOL,
  55.     0x000E,                /* codes 1-3 recognized */
  56.  
  57.     Pap,
  58.     PAP_REQ_TRY,
  59.     PAP_FAIL_MAX,
  60.     0,
  61.     PAP_TIMEOUT * 1000L,
  62.  
  63.     pap_free,
  64.  
  65.     fsm_no_action,        /* pap_reset, */
  66.     fsm_no_action,        /* pap_starting, */
  67.     fsm_no_action,        /* pap_opening, */
  68.     fsm_no_action,        /* pap_closing, */
  69.     fsm_no_action,        /* pap_stopping, */
  70.  
  71.     pap_makereq,
  72.     fsm_no_check,        /* pap_request, */
  73.     fsm_no_check,        /* pap_ack, */
  74.     fsm_no_check,        /* pap_nak, */
  75.     fsm_no_check,        /* pap_reject */
  76. };
  77.  
  78.  
  79. /****************************************************************************/
  80.  
  81. /* "ppp <iface> pap" subcommands */
  82. static struct cmds Papcmds[] = {
  83.     "timeout",    doppp_timeout,    0,    0,    NULLCHAR,
  84.     "try",        doppp_try,    0,    0,    NULLCHAR,
  85.     "user",        dopap_user,    0,    0,    NULLCHAR,
  86.     NULLCHAR,
  87. };
  88.  
  89.  
  90. int
  91. doppp_pap(argc,argv,p)
  92. int argc;
  93. char *argv[];
  94. void *p;
  95. {
  96.     register struct iface *ifp = p;
  97.     register struct ppp_s *ppp_p = ifp->edv;
  98.  
  99.     return subcmd(Papcmds, argc, argv, &(ppp_p->fsm[Pap]));
  100. }
  101.  
  102.  
  103. /* Set user/password */
  104. int
  105. dopap_user(argc,argv,p)
  106. int argc;
  107. char *argv[];
  108. void *p;
  109. {
  110.     register struct fsm_s *fsm_p = p;
  111.     register struct pap_s *pap_p = fsm_p->pdv;
  112.  
  113.     if (argc < 2) {
  114.         tprintf("%s\n",
  115.             (pap_p->username == NULLCHAR) ? "None" : pap_p->username);
  116.         return 0;
  117.     }
  118.     free(pap_p->username);
  119.     pap_p->username = NULLCHAR;
  120.     free(pap_p->password);
  121.     pap_p->password = NULLCHAR;
  122.  
  123.     if (stricmp(argv[1],"none") != 0) {
  124.         pap_p->username = strdup(argv[1]);
  125.         if (argc > 2) {
  126.             pap_p->password = strdup(argv[2]);
  127.         } else {
  128.             pap_pwdlookup( pap_p );
  129.         }
  130.     }
  131.     return 0;
  132. }
  133.  
  134.  
  135. /****************************************************************************/
  136. /* Bring up a session on the console for for the username/password.
  137.  * Return a NULLCHAR in either username or password if aborted.
  138.  */
  139. static void
  140. pap_monitor(unused, v1, v2)
  141. int unused;
  142. void *v1;
  143. void *v2;
  144. {
  145.     struct iface *iface = v1;
  146.     struct fsm_s *fsm_p = v2;
  147.     struct pap_s *pap_p = fsm_p->pdv;
  148.     char buf[21];
  149.     struct session *sp;
  150.     int wait_code = 0;
  151.  
  152.     /* Allocate a session control block */
  153.     if((sp = newsession("PPP/PAP",PPPPASS,0)) == NULLSESSION){
  154.         tputs(TooManySessions);
  155.         return;
  156.     }
  157.  
  158.     while ( !main_exit && wait_code == 0 ) {
  159.         /* get user name */
  160.         if (pap_p->username == NULLCHAR) {
  161.             tprintf ("%s: PPP/PAP  Username: ", iface->name);
  162.             usflush(sp->output);
  163.             if (recvline(sp->input,buf,20) > 0) {
  164.                 rip(buf);
  165.                 if (strlen(buf) > 0) {
  166.                     pap_p->username = strdup(buf);
  167.                 }
  168.             }
  169.         } else {
  170.             tprintf ("%s: PPP/PAP  Username: %s\n",
  171.                 iface->name, pap_p->username);
  172.             usflush(sp->output);
  173.         }
  174.  
  175.         /* get pass word */
  176.         if (pap_p->username != NULLCHAR
  177.          && pap_p->password == NULLCHAR) {
  178.             /* turn off echo */
  179.             sp->ttystate.echo = 0;
  180.             tprintf("%s: PPP/PAP  Password: ",iface->name);
  181.             usflush(sp->output);
  182.             if (recvline(sp->input,buf,20) > 0) {
  183.                 rip(buf);
  184.                 if ( strlen(buf) > 0 ) {
  185.                     pap_p->password = strdup(buf);
  186.                 }
  187.             }
  188.             tprintf("\n");
  189.             usflush(sp->output);
  190.             /* Turn echo back on */
  191.             sp->ttystate.echo = 1;
  192.         }
  193.  
  194.         /* send pap request */
  195.         fsm_sendreq(fsm_p);
  196.         wait_code = pwait ( pap_p );
  197.  
  198.         /* show ack/nak reply */
  199.         if ( wait_code != EABORT && pap_p->message != NULLCHAR ) {
  200.             tprintf ("%s: PPP/PAP  %s\n",
  201.                 iface->name, pap_p->message );
  202.         }
  203.         tprintf ( "\n" );
  204.         usflush(sp->output);
  205.  
  206.     }
  207.  
  208.     /* clean up */
  209.     if ( wait_code != EABORT ) {
  210.         pause ( 10000L );
  211.     }
  212.     freesession(sp);
  213.     pap_p->pp = NULLPROC;
  214. }
  215.  
  216.  
  217. /* Check the FTP userfile for this user; get password if available */
  218. static void
  219. pap_pwdlookup(pap_p)
  220. struct pap_s *pap_p;
  221. {
  222.     char *buf;
  223.     char *password;
  224.     int permission;
  225.  
  226.     if ( pap_p->username == NULLCHAR )
  227.         return;
  228.  
  229.     if ( (buf = userlookup( pap_p->username, &password, NULLCHARP,
  230.             &permission, NULL )) == NULLCHAR )
  231.         return;
  232.  
  233.     /* Check permissions for this user */
  234.     if ( (permission & PPP_PWD_LOOKUP) == 0 ) {
  235.         /* Not in ftpuser file for password lookup */
  236.         free(buf);
  237.         return;
  238.     }
  239.  
  240.     /* Save the password from this userfile record */
  241.     if ( strlen(password) != 0 )
  242.         pap_p->password = strdup(password);
  243.     free(buf);
  244. }
  245.  
  246.  
  247. /*******************************************/
  248. /* Verify user and password sent by remote host */
  249. static int
  250. pap_verify(username,password)
  251. char *username;
  252. char *password;
  253. {
  254.     int privs;
  255.     char *path;
  256.     int anony = 0;
  257.  
  258.     /* Use same login as FTP server */
  259.     path = mallocw(128);
  260.     privs = userlogin(username,password,&path,128,&anony);
  261.     free(path);
  262.  
  263.     /* Check privs for this user */
  264.     if (privs == -1) {
  265.         trace_log(PPPiface,"PAP: username/password incorrect or not found: %s",
  266.                 username);
  267.         return -1;
  268.     }
  269.  
  270.     if ((privs & PPP_ACCESS_PRIV) == 0) {
  271.         trace_log(PPPiface,"PAP: no permission for PPP access: %s",
  272.                 username);
  273.         return -1;
  274.     }
  275.     return 0;
  276. }
  277.  
  278.  
  279. /****************************************************************************/
  280. /* Build a request to send to remote host */
  281. static struct mbuf *
  282. pap_makereq(fsm_p)
  283. struct fsm_s *fsm_p;
  284. {
  285.     struct pap_s *pap_p = fsm_p->pdv;
  286.     struct mbuf *req_bp = NULLBUF;
  287.     register char *cp;
  288.     int len;
  289.  
  290.     PPP_DEBUG_ROUTINES("pap_makereq()");
  291.  
  292.     if ( pap_p->username == NULLCHAR
  293.      ||  pap_p->password == NULLCHAR ) {
  294.         fsm_log( fsm_p, "NULL username or password" );
  295.         return NULLBUF;
  296.     }
  297.  
  298. #ifdef PPP_DEBUG_OPTIONS
  299.     if (PPPtrace & PPP_DEBUG_OPTIONS)
  300.         trace_log(PPPiface, "    making user id %s", pap_p->username);
  301. #endif
  302.  
  303.     /* Get buffer for authenticate request packet */
  304.     len = 2 + strlen(pap_p->username) + strlen(pap_p->password);
  305.     if ((req_bp = alloc_mbuf(len)) == NULLBUF)
  306.         return NULLBUF;
  307.  
  308.     /* Load user id and password for authenticate packet */
  309.     cp = req_bp->data;
  310.     *cp++ = (char)strlen(pap_p->username);
  311.     if ( strlen(pap_p->username) > 0 )
  312.         cp = strcpy(cp, pap_p->username);
  313.  
  314.     *cp++ = (char)strlen(pap_p->password);
  315.     if ( strlen(pap_p->password) > 0 )
  316.         cp = strcpy(cp, pap_p->password);
  317.  
  318.     req_bp->cnt += len;
  319.     return(req_bp);
  320. }
  321.  
  322.  
  323. /****************************************************************************/
  324.  
  325. /* abandon PAP attempt; shutdown LCP layer */
  326. static void
  327. pap_shutdown(fsm_p)
  328. struct fsm_s *fsm_p;
  329. {
  330.     struct ppp_s *ppp_p = fsm_p->ppp_p;
  331.  
  332.     PPP_DEBUG_ROUTINES("pap_shutdown()");
  333.  
  334.     if (PPPtrace > 1)
  335.         fsm_log( fsm_p, "Failed; close connection" );
  336.  
  337.     fsm_close( &(ppp_p->fsm[Lcp]) );
  338. }
  339.  
  340.  
  341. /* Configuration negotiation complete */
  342. static void
  343. pap_opening(fsm_p, flag)
  344. struct fsm_s *fsm_p;
  345. int flag;
  346. {
  347.     register struct ppp_s *ppp_p = fsm_p->ppp_p;
  348.  
  349.     fsm_log(fsm_p, "Open");
  350.  
  351.     stop_timer(&(fsm_p->timer));
  352.  
  353.     if ( !((fsm_p->flags &= ~flag) & (PPP_AP_LOCAL | PPP_AP_REMOTE)) ) {
  354.         fsm_p->state = fsmOPENED;
  355.     }
  356.     ppp_p->flags &= ~flag;
  357.     ppp_ready(ppp_p);
  358. }
  359.  
  360.  
  361. /****************************************************************************/
  362. /* Check request from remote host */
  363. static int
  364. pap_request(fsm_p, hdr, data)
  365. struct fsm_s *fsm_p;
  366. struct config_hdr *hdr;
  367. struct mbuf *data;
  368. {
  369.     struct mbuf *reply_bp;
  370.     int result;
  371.     char *message;
  372.     int mess_length;
  373.     char *username = NULLCHAR;
  374.     int userlen;
  375.     char *password = NULLCHAR;
  376.     int passwordlen;
  377.  
  378.     PPP_DEBUG_ROUTINES("pap_request()");
  379.  
  380.     /* Extract userID/password sent by remote host */
  381.     if ( (userlen = pullchar(&data)) != -1 ) {
  382.         register int i;
  383.         register char *cp;
  384.  
  385.         cp = username = mallocw(userlen+1);
  386.         for ( i = userlen; i-- > 0; ) {
  387.             *cp++ = PULLCHAR(&data);
  388.         }
  389.         *cp = '\0';
  390.     }
  391.  
  392. #ifdef PPP_DEBUG_OPTIONS
  393.     if (PPPtrace & PPP_DEBUG_OPTIONS)
  394.         trace_log(PPPiface,"    checking user: %s", username);
  395. #endif
  396.  
  397.     if ( (passwordlen = pullchar(&data)) != -1 ) {
  398.         register int i;
  399.         register char *cp;
  400.  
  401.         cp = password = mallocw(passwordlen+1);
  402.         for ( i = passwordlen; i-- > 0; ) {
  403.             *cp++ = PULLCHAR(&data);
  404.         }
  405.         *cp = '\0';
  406.     }
  407.  
  408. #ifdef PPP_DEBUG_OPTIONS
  409.     if (PPPtrace & PPP_DEBUG_OPTIONS)
  410.         trace_log(PPPiface,"    checking password: %s", password);
  411. #endif
  412.  
  413.     if (pap_verify(username,password) == 0) {
  414.         free( fsm_p->ppp_p->peername );
  415.         fsm_p->ppp_p->peername = strdup(username);
  416.         result = CONFIG_ACK;
  417.         message = " Welcome";
  418.     } else {
  419.         result = CONFIG_NAK;
  420.         message = " Invalid username or password";
  421.     }
  422.  
  423.     /* the space at the beginning of the message is crucial */
  424.     /* it is replaced with the length of the message */
  425.     mess_length = strlen(message);
  426.     reply_bp = qdata(message,mess_length);
  427.     reply_bp->data[0] = (char)(mess_length - 1);
  428.  
  429.     fsm_send(fsm_p, result, hdr->id, reply_bp);
  430.  
  431.     if (result == CONFIG_NAK) {
  432.         if ( fsm_p->retry_nak > 0 ) {
  433.             fsm_p->retry_nak--;
  434.         } else {
  435.             pap_shutdown(fsm_p);
  436.         }
  437.     }
  438.     free_p(data);
  439.     free(username);
  440.     free(password);
  441.     return (result != CONFIG_ACK);
  442. }
  443.  
  444.  
  445. /* Check acknowledgement from remote host */
  446. static int
  447. pap_check(fsm_p, hdr, data)
  448. struct fsm_s *fsm_p;
  449. struct config_hdr *hdr;
  450. struct mbuf *data;
  451. {
  452.     struct pap_s *pap_p = fsm_p->pdv;
  453.     char *message;
  454.     int mess_length;
  455.     int full_length;
  456.     int len;
  457.  
  458.     PPP_DEBUG_ROUTINES("pap_check()");
  459.  
  460.     /* ID field must match last request we sent */
  461.     if (hdr->id != fsm_p->lastid) {
  462.         PPP_DEBUG_CHECKS("PAP: wrong ID");
  463.         tprintf ("id mismatch hdrid=%d, lastid=%d\n",
  464.             hdr->id, fsm_p->lastid);
  465.         free_p(data);
  466.         return -1;
  467.     }
  468.  
  469.     /* Log ASCII message from remote host, if any */
  470.     if ( (mess_length = pullchar(&data)) != -1 ) {
  471.         message = mallocw( mess_length+1 );
  472.         full_length = len_p(data);
  473.         len = dqdata(data, message, mess_length);
  474.         message[len] = '\0';
  475.  
  476.         free( pap_p->message );
  477.         pap_p->message = message;
  478.  
  479.         if (PPPtrace) {
  480.             trace_log(PPPiface,"%s PPP/PAP %s %s: %s",
  481.                 fsm_p->ppp_p->iface->name,
  482.                 (len < mess_length) ? "Short"
  483.                    : (mess_length < full_length) ? "Long"
  484.                     : "Valid",
  485.                 (hdr->code == CONFIG_ACK) ? "Ack" : "Nak",
  486.                 message);
  487.         }
  488.         return (len < mess_length  ||  mess_length < full_length);
  489.     }
  490.     free_p(data);
  491.     PPP_DEBUG_CHECKS( "PAP: missing message count" );
  492.     return -1;
  493. }
  494.  
  495.  
  496. /************************************************************************/
  497. /*            E V E N T   P R O C E S S I N G            */
  498. /************************************************************************/
  499.  
  500. /* Process incoming packet */
  501. void
  502. pap_proc(fsm_p,bp)
  503. struct fsm_s *fsm_p;
  504. struct mbuf *bp;
  505. {
  506.     struct pap_s *pap_p = fsm_p->pdv;
  507.     struct config_hdr hdr;
  508.  
  509.     PPPtrace = fsm_p->ppp_p->trace;
  510.     PPPiface = fsm_p->ppp_p->iface;
  511.  
  512.     if ( ntohcnf(&hdr, &bp) == -1 )
  513.         fsm_log( fsm_p, "short authentication packet" );
  514.  
  515.     if (PPPtrace > 1)
  516.         trace_log(PPPiface, "%s PPP/%s Recv,"
  517.             "  option: %s, id: %d, len: %d",
  518.             fsm_p->ppp_p->iface->name,
  519.             fsm_p->pdc->name,
  520.             fsmCodes[hdr.code],
  521.             hdr.id,    hdr.len);
  522.  
  523.     hdr.len -= CONFIG_HDR_LEN;        /* Length includes envelope */
  524.     trim_mbuf(&bp, hdr.len);        /* Trim off padding */
  525.  
  526.     switch(hdr.code) {
  527.     case CONFIG_REQ:
  528.         if ( pap_request(fsm_p, &hdr, bp) == 0) {
  529.             pap_opening(fsm_p, PPP_AP_LOCAL);
  530.         }
  531.         break;
  532.  
  533.     case CONFIG_ACK:
  534.         if (pap_check(fsm_p, &hdr, bp) == 0) {
  535.             alert ( pap_p->pp, -1 );
  536.             pap_opening(fsm_p, PPP_AP_REMOTE);
  537.         }
  538.         break;
  539.  
  540.     case CONFIG_NAK:
  541.         if (pap_check(fsm_p, &hdr, bp) == 0) {
  542.             stop_timer(&(fsm_p->timer));
  543.  
  544.             /* Must have sent a bad username or password */
  545.             free ( pap_p->username );
  546.             pap_p->username = NULLCHAR;
  547.             free ( pap_p->password );
  548.             pap_p->password = NULLCHAR;
  549.  
  550.             psignal ( pap_p, 1 );
  551.         }
  552.         break;
  553.  
  554.     default:
  555.         if (PPPtrace)
  556.             trace_log(PPPiface, "%s PPP/Pap Unknown packet type: %d;"
  557.                 " dropping packet",
  558.                 fsm_p->ppp_p->iface->name,
  559.                 hdr.code);
  560.         free_p(bp);
  561.         break;
  562.     }
  563. }
  564.  
  565.  
  566. /* Timeout while waiting for reply from remote host */
  567. static void
  568. pap_timeout(vp)
  569. void *vp;
  570. {
  571.     struct fsm_s *fsm_p = (struct fsm_s *)vp;
  572.     struct pap_s *pap_p = fsm_p->pdv;
  573.  
  574.     PPPtrace = fsm_p->ppp_p->trace;
  575.     PPPiface = fsm_p->ppp_p->iface;
  576.  
  577.     fsm_log( fsm_p, "Timeout" );
  578.  
  579.     if (fsm_p->retry > 0) {
  580.         free ( pap_p->message );
  581.         pap_p->message = strdup("Request timeout");
  582.         psignal ( pap_p, 1 );
  583.     } else {
  584.         free ( pap_p->message );
  585.         pap_p->message = strdup("Request retry exceeded");
  586.         psignal ( pap_p, 1 );
  587.         pwait ( NULL );
  588.         fsm_log(fsm_p, "Request retry exceeded");
  589.         pap_shutdown(fsm_p);
  590.     }
  591. }
  592.  
  593.  
  594. /************************************************************************/
  595. /*            I N I T I A L I Z A T I O N            */
  596. /************************************************************************/
  597.  
  598. void
  599. pap_down(fsm_p)
  600. struct fsm_s *fsm_p;
  601. {
  602.     struct pap_s *pap_p = fsm_p->pdv;
  603.  
  604.     if ( pap_p == NULL )
  605.         return;
  606.  
  607.     PPPtrace = fsm_p->ppp_p->trace;
  608.     PPPiface = fsm_p->ppp_p->iface;
  609.  
  610.     fsm_log(fsm_p, "Down");
  611.  
  612.     fsm_p->flags = FALSE;
  613.  
  614.     switch ( fsm_p->state ) {
  615.     case fsmREQ_Sent:
  616.         stop_timer(&(fsm_p->timer));
  617.         alert ( pap_p->pp, EABORT );
  618.         /* fallthru */
  619.     case fsmOPENED:
  620.     case fsmLISTEN:
  621.     case fsmTERM_Sent:
  622.         fsm_p->state = fsmCLOSED;
  623.         break;
  624.  
  625.     case fsmCLOSED:
  626.         /* Already closed; nothing to do */
  627.         break;
  628.     };
  629. }
  630.  
  631.  
  632. static void
  633. pap_free(fsm_p)
  634. struct fsm_s *fsm_p;
  635. {
  636.     struct pap_s *pap_p = fsm_p->pdv;
  637.  
  638.     free( pap_p->username );
  639.     free( pap_p->password );
  640.     free( pap_p->message );
  641. }
  642.  
  643.  
  644. /* Initialize configuration structure */
  645. void
  646. pap_init(ppp_p)
  647. struct ppp_s *ppp_p;
  648. {
  649.     struct fsm_s *fsm_p = &(ppp_p->fsm[Pap]);
  650.     struct timer *t;
  651.  
  652.     PPPtrace = ppp_p->trace;
  653.     PPPiface = ppp_p->iface;
  654.  
  655.     PPP_DEBUG_ROUTINES("pap_init()");
  656.  
  657.     if (fsm_p->pdv != NULL)
  658.         return;        /* already initialized */
  659.  
  660.     fsm_p->ppp_p = ppp_p;
  661.     fsm_p->pdc = &pap_constants;
  662.     fsm_p->pdv = callocw(1,sizeof(struct pap_s));
  663.  
  664.     fsm_p->try_req = fsm_p->pdc->try_req;
  665.     fsm_p->try_nak = fsm_p->pdc->try_nak;
  666.     fsm_p->try_terminate = fsm_p->pdc->try_terminate;
  667.  
  668.     fsm_p->state = fsmCLOSED;
  669.     fsm_p->retry = fsm_p->try_req;
  670.     fsm_p->retry_nak = fsm_p->try_nak;
  671.  
  672.     /* Initialize timer */
  673.     t = &(fsm_p->timer);
  674.     t->func = (void (*)())pap_timeout;
  675.     t->arg = (void *)fsm_p;
  676.     set_timer(t, fsm_p->pdc->timeout);
  677.     fsm_timer(fsm_p);
  678.     stop_timer(t);
  679. }
  680. /* Initialize state machine for local */
  681. int
  682. pap_local(ppp_p)
  683. struct ppp_s *ppp_p;
  684. {
  685.     struct fsm_s *fsm_p = &(ppp_p->fsm[Pap]);
  686.  
  687.     PPPtrace = ppp_p->trace;
  688.  
  689.     PPP_DEBUG_ROUTINES("pap_local()");
  690.  
  691.     fsm_p->state = fsmLISTEN;
  692.     fsm_p->flags |= PPP_AP_LOCAL;
  693.     ppp_p->flags |= PPP_AP_LOCAL;
  694.     fsm_p->retry = fsm_p->try_req;
  695.     return 0;
  696. }
  697.  
  698.  
  699. /* Initialize state machine for remote */
  700. int
  701. pap_remote(ppp_p)
  702. struct ppp_s *ppp_p;
  703. {
  704.     struct fsm_s *fsm_p = &(ppp_p->fsm[Pap]);
  705.     struct pap_s *pap_p = fsm_p->pdv;
  706.     char *ifn;
  707.  
  708.     PPPtrace = ppp_p->trace;
  709.  
  710.     PPP_DEBUG_ROUTINES("pap_remote()");
  711.  
  712.     fsm_p->state = fsmREQ_Sent;
  713.     fsm_p->flags |= PPP_AP_REMOTE;
  714.     ppp_p->flags |= PPP_AP_REMOTE;
  715.  
  716.     /* build a process/session to monitor user/password progress */
  717.     ifn = if_name( ppp_p->iface, " PAP" );
  718.     pap_p->pp = newproc( ifn,
  719.         512, pap_monitor, 0, ppp_p->iface, fsm_p, 0);
  720.     free( ifn );
  721.  
  722.     return 0;
  723. }
  724.  
  725.  
  726.